package net.wanho.config;

import net.wanho.shiro.filter.JwtFilter;
import net.wanho.shiro.matcher.JwtMatcher;
import net.wanho.shiro.realm.ShiroRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Shiro配置类
 */
@Configuration
public class ShiroConfig {

    /**
     * ShiroFilter过滤器
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

        // 设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        // 注册过滤器
        Map<String, Filter> filterMap = new LinkedHashMap<>();
        filterMap.put("jwtFilter", new JwtFilter());
        shiroFilterFactoryBean.setFilters(filterMap);

        // 设置过滤url规则
        Map<String,String> map = new LinkedHashMap<>(); // 有序的map
        map.put("/captchaImage", "anon"); // anon表示可以匿名访问
        map.put("/login", "anon");
        // 放行swagger
        map.put("/docs", "anon");
        map.put("/doc.html", "anon");
        map.put("/webjars/springfox-swagger-ui/**", "anon");
        map.put("/swagger-resources/**", "anon");
        map.put("/v2/api-docs", "anon");

        map.put("/**", "jwtFilter"); // /**表示所有的请求都必须认证通过才可以访问
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

        return shiroFilterFactoryBean;
    }

    /**
     * 安全管理器
     */
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

        // 设置Realm
        securityManager.setRealm(realm);

        return securityManager;
    }

    /**
     * 自定义Realm
     */
    @Bean
    public Realm getRealm(){
        ShiroRealm realm = new ShiroRealm();
        // 使用JwtMatcher进行凭证匹配，对token判断
        realm.setCredentialsMatcher(new JwtMatcher());
        return realm;
    }

}
